using PlayFab.Internal;
using System;
using System.Collections.Generic;
using System.Text;

namespace PlayFab
{
    /// <summary>
    /// Error codes returned by PlayFabAPIs
    /// </summary>
    public enum PlayFabErrorCode
    {
        Success = 0,
        Unknown = 1,
        ConnectionError = 2,
        JsonParseError = 3,
        <% for(var i=1; i<errorList.length-1; i++) { var errorProps = errors[errorList[i]] %><%- errorProps.name %> = <%- errorProps.id %>,
        <% } %><% var errorProps = errors[errorList[errorList.length-1]] %><%- errorProps.name %> = <%- errorProps.id %>
    }

    public class PlayFabError
    {
        public int HttpCode;
        public string HttpStatus;
        public PlayFabErrorCode Error;
        public string ErrorMessage;
        public Dictionary<string, string[]> ErrorDetails;

        private static readonly StringBuilder Sb = new StringBuilder();
        /// <summary>
        /// This converts the PlayFabError into a human readable string describing the error.
        /// If error is not found, it will return the http code, status, and error
        /// </summary>
        /// <returns>A description of the error that we just incur.</returns>
        public string GenerateErrorReport()
        {
            Sb.Length = 0;
            if (ErrorMessage != null)
            {
                Sb.Append(ErrorMessage);
            }
            else
            {
                Sb.Append("Http Code: " + HttpCode.ToString() + "\nHttp Status: " + HttpStatus + "\nError: " + Error.ToString() + "\n");
            }

            if (ErrorDetails == null)
                return Sb.ToString();

            foreach (var pair in ErrorDetails)
            {
                foreach (var eachMsg in pair.Value)
                    Sb.Append(pair.Key).Append(": ").Append(eachMsg);
            }
            return Sb.ToString();
        }
    };

    public class PlayFabBaseResult
    {
        public object CustomData;
        public PlayFabError Error;
    }

    public class PlayFabResult<TResult> : PlayFabBaseResult where TResult : PlayFabResultCommon
    {
        public TResult Result;
    }

    public delegate void ErrorCallback(PlayFabError error);

    public class PlayFabException : Exception
    {
        public readonly PlayFabExceptionCode Code;
        public PlayFabException(PlayFabExceptionCode code, string message) : base(message)
        {
            Code = code;
        }
    }

    public enum PlayFabExceptionCode
    {
        AuthContextRequired,
        DeveloperKeyNotSet,
        EntityTokenNotSet,
        NotLoggedIn,
        TitleNotSet,
        PluginAmbiguity,
        PluginNotFound
    }
}
